package com.wondertek.service.service.business.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wondertek.common.exception.AppException;
import com.wondertek.common.util.base.SmsUtil;
import com.wondertek.common.util.base.VoiceNoticeUtil;
import com.wondertek.service.dto.business.req.AlarmNoticeSettingAddReq;
import com.wondertek.service.dto.business.req.AlarmNoticeSettingQueryReq;
import com.wondertek.service.dto.business.req.AlarmNoticeSettingUpdateReq;
import com.wondertek.service.entity.business.AlarmNoticeSettingPo;
import com.wondertek.service.mapper.business.AlarmNoticeSettingMapper;
import com.wondertek.service.service.business.IAlarmNoticeSettingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;

/**
 * @author wangyu
 */
@Service
@Slf4j
public class AlarmNoticeSettingServiceImpl extends ServiceImpl<AlarmNoticeSettingMapper, AlarmNoticeSettingPo> implements IAlarmNoticeSettingService {

    @Override
    public Page<AlarmNoticeSettingPo> page(AlarmNoticeSettingQueryReq alarmNoticeSettingQueryReq) {
        LambdaQueryWrapper<AlarmNoticeSettingPo> queryWrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(alarmNoticeSettingQueryReq.getPhone())) {
            queryWrapper.eq(AlarmNoticeSettingPo::getPhone, alarmNoticeSettingQueryReq.getPhone());
        }
        queryWrapper.eq(AlarmNoticeSettingPo::getDeviceId, alarmNoticeSettingQueryReq.getDeviceId());
        queryWrapper.orderByDesc(AlarmNoticeSettingPo::getCreateTime);
        return this.page(new Page<>(alarmNoticeSettingQueryReq.getPageNo(), alarmNoticeSettingQueryReq.getPageSize()), queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(AlarmNoticeSettingAddReq alarmNoticeSettingAddReq) {
        long count = this.lambdaQuery().eq(AlarmNoticeSettingPo::getPhone, alarmNoticeSettingAddReq.getPhone())
                .eq(AlarmNoticeSettingPo::getDeviceId, alarmNoticeSettingAddReq.getDeviceId())
                .count();
        if (count > 0) {
            throw new AppException("alarm.notice.same.phone.not.partition");
        }
        AlarmNoticeSettingPo alarmNoticeSettingPo = new AlarmNoticeSettingPo();
        BeanUtil.copyProperties(alarmNoticeSettingAddReq, alarmNoticeSettingPo);
        this.save(alarmNoticeSettingPo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSysJob(AlarmNoticeSettingUpdateReq alarmNoticeSettingUpdateReq) {
        AlarmNoticeSettingPo alarmNoticeSettingPo = this.getById(alarmNoticeSettingUpdateReq.getId());
        if (!StrUtil.equals(alarmNoticeSettingPo.getPhone(), alarmNoticeSettingUpdateReq.getPhone())) {
            long count = this.lambdaQuery().eq(AlarmNoticeSettingPo::getPhone, alarmNoticeSettingUpdateReq.getPhone())
                    .eq(AlarmNoticeSettingPo::getDeviceId, alarmNoticeSettingUpdateReq.getDeviceId())
                    .count();
            if (count > 0) {
                throw new AppException("alarm.notice.same.phone.not.partition");
            }
        }
        BeanUtil.copyProperties(alarmNoticeSettingUpdateReq, alarmNoticeSettingPo);
        alarmNoticeSettingPo.setUpdateBy(null);
        alarmNoticeSettingPo.setUpdateTime(null);
        this.updateById(alarmNoticeSettingPo);
    }


    @Async("threadPoolTaskExecutor")
    @Override
    public void sendSmsAndSendVoice(String deviceId, String content) {
        List<AlarmNoticeSettingPo> list = this.lambdaQuery().eq(AlarmNoticeSettingPo::getDeviceId, deviceId).list();
        list = list.stream().filter(item -> item.getSmsNotice() == 1 || item.getPhoneNotice() == 1).toList();
        if (CollUtil.isNotEmpty(list)) {
            for (AlarmNoticeSettingPo alarmNoticeSettingPo : list) {
                String countryCode = alarmNoticeSettingPo.getCountryCode();
                countryCode = countryCode.replaceAll("\\+", "");
                if (1 == alarmNoticeSettingPo.getSmsNotice()) {
                    try {
                        SmsUtil.sendMessage(countryCode + alarmNoticeSettingPo.getPhone(), content);
                    } catch (Exception e) {
                        log.error("告警短信通知,参数：{}", JSONUtil.toJsonStr(alarmNoticeSettingPo), e);
                    }
                }
                if (1 == alarmNoticeSettingPo.getPhoneNotice()) {
                    VoiceNoticeUtil.send(countryCode, Collections.singletonList(alarmNoticeSettingPo.getPhone()), content);
                }
            }
        }
    }
}
